package com.dommettj.rawfix.gui;

import com.dommettj.rawfix.gui.event.GuiEventCallback;
import com.dommettj.rawfix.gui.event.GuiEventHandler;
import com.dommettj.rawfix.settings.Settings;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
import java.util.Collection;

public class RawFixMainFrame extends JFrame implements ActionListener, WindowListener {

    public static final String MAIN_WINDOW = "MainWindow";
    public static final String LOGON_BUTTON = "LogonButton";
    public static final String LOGOFF_BUTTON = "LogoffButton";
    public static final String SEND_BUTTON = "SendButton";
    public static final String LOGBOX_DISPLAY = "LogBoxDisplay";
    public static final String MESSAGE_DISPLAY = "MessageDisplay";
    private static final String LOGON_COMMAND = "LOGON";
    private static final String LOGOFF_COMMAND = "LOGOFF";
    private static final String SEND_COMMAND = "SEND";
    private static final int BORDER = 20;

    private final Collection<GuiEventHandler> eventHandlers = new ArrayList<GuiEventHandler>();
    private final GuiEventCallback eventCallback;
    private final Dimension buttonDimension = new Dimension(80, 30);
    private JTextArea messageBox = new JTextArea(20, 50);
    private JTextArea logBox = new JTextArea(10, 50);

    public RawFixMainFrame(final Settings settings) {

        final JPanel centralPanel = new JPanel(new BorderLayout());
        centralPanel.setBorder(BorderFactory.createEmptyBorder(BORDER, BORDER, BORDER, BORDER));

        final JPanel textPanel = new JPanel(new BorderLayout());
        textPanel.add(createMessagePanel(), BorderLayout.NORTH);
        textPanel.add(createLogPanel(), BorderLayout.SOUTH);

        centralPanel.add(createButtonPanel(), BorderLayout.SOUTH);
        centralPanel.add(textPanel, BorderLayout.NORTH);

        final RawFixMenu menu = new RawFixMenu(settings, eventHandlers);
        setJMenuBar(menu.create());

        eventCallback = new GuiEventCallbackImpl(logBox);

        addWindowListener(this);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(centralPanel, BorderLayout.CENTER);
        setTitle("RawFix");
        setName(MAIN_WINDOW);
        pack();

        GuiHelper.centreWindow(this);
    }

    public void registerEventHandler(final GuiEventHandler handler) {
        eventHandlers.add(handler);
    }

    public GuiEventCallback getEventCallback() {
        return eventCallback;
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {

        if (actionEvent.getActionCommand().equals(LOGON_COMMAND)) {
            handleLogon();
        } else if (actionEvent.getActionCommand().equals(LOGOFF_COMMAND)) {
            handleLogoff();
        } else if (actionEvent.getActionCommand().equals(SEND_COMMAND)) {
            handleSend(messageBox.getText());
        }
    }

    @Override
    public void windowClosing(WindowEvent windowEvent) {
        for (GuiEventHandler handler : eventHandlers) {
            handler.close();
        }
    }

    @Override
    public void windowClosed(WindowEvent windowEvent) { }

    @Override
    public void windowOpened(WindowEvent windowEvent) { }

    @Override
    public void windowIconified(WindowEvent windowEvent) { }

    @Override
    public void windowDeiconified(WindowEvent windowEvent) { }

    @Override
    public void windowActivated(WindowEvent windowEvent) { }

    @Override
    public void windowDeactivated(WindowEvent windowEvent) { }

    private JPanel createButtonPanel() {

        final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));

        final JButton logonButton = new JButton("Logon");
        logonButton.setName(LOGON_BUTTON);
        logonButton.setPreferredSize(buttonDimension);
        logonButton.addActionListener(this);
        logonButton.setActionCommand(LOGON_COMMAND);

        final JButton logoffButton = new JButton("Logoff");
        logoffButton.setName(LOGOFF_BUTTON);
        logoffButton.setPreferredSize(buttonDimension);
        logoffButton.addActionListener(this);
        logoffButton.setActionCommand(LOGOFF_COMMAND);

        buttonPanel.add(logonButton);
        buttonPanel.add(logoffButton);
        return buttonPanel;
    }

    private JPanel createLogPanel() {

        final JPanel logPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        logBox.setName(LOGBOX_DISPLAY);
        logBox.setEditable(false);

        final JScrollPane logScrollBox = new JScrollPane(logBox);
        logPanel.add(logScrollBox);
        return logPanel;
    }

    private JPanel createMessagePanel() {

        final JPanel messagePanel = new JPanel(new BorderLayout());

        final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        final JButton sendButton = new JButton("Fix up and send");
        sendButton.setName(SEND_BUTTON);
        sendButton.setPreferredSize(new Dimension(160, 30));
        sendButton.addActionListener(this);
        sendButton.setActionCommand(SEND_COMMAND);

        buttonPanel.add(sendButton);

        final JPanel messageBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        messageBox.setName(MESSAGE_DISPLAY);

        final JScrollPane messageScrollBox = new JScrollPane(messageBox);
        messageBoxPanel.add(messageScrollBox);

        messagePanel.add(messageBoxPanel, BorderLayout.NORTH);
        messagePanel.add(buttonPanel, BorderLayout.SOUTH);

        return messagePanel;
    }

    private void handleLogon() {
        for (GuiEventHandler handler : eventHandlers) {
            handler.logon();
        }
    }

    private void handleLogoff() {
        for (GuiEventHandler handler : eventHandlers) {
            handler.logoff();
        }
    }

    private void handleSend(final String message) {
        for (GuiEventHandler handler : eventHandlers) {
            handler.sendMessage(message);
        }
    }
}
